﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Xml.Linq;
using System.IO;

namespace OAuthAccess
{
    /// <summary>
    /// Represents Response of OAuthRequest.
    /// </summary>
    public class OAuthResponse
    {
        HttpWebResponse _response = null;
        XElement _xElement = null;

        internal OAuthResponse(HttpWebResponse response)
            :this(response,0)
        {

        }

        internal OAuthResponse(HttpWebResponse response, int retryCount)
            : this(response, true,retryCount)
        {
        }

        internal OAuthResponse(HttpWebResponse response, bool isSuccess, int retryCount)
        {
            IsSuccess = isSuccess;

            if (response == null)
            {
                throw new OAuthAccessException("Response is Null");
            }

            _response = response;

            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {
                ResponseText = sr.ReadToEnd();
            }

            ContentEncoding = _response.ContentEncoding;
            CharacterSet = _response.CharacterSet;
            ContentLength = _response.ContentLength;
            ContentType = _response.ContentType;
            Cookies = _response.Cookies;
            Headers = _response.Headers;
            IsFromCache = _response.IsFromCache;
            IsMutuallyAuthenticated = _response.IsMutuallyAuthenticated;
            LastModified = _response.LastModified;
            Method = _response.Method;
            ProtocolVersion = _response.ProtocolVersion;
            ResponseUri = _response.ResponseUri;
            Server = _response.Server;
            StatusCode = _response.StatusCode;
            StatusDescription = _response.StatusDescription;
        }

        /// <summary>
        /// Represents the request which was success or failed.
        /// </summary>
        public bool IsSuccess
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the string of ResponseBody.
        /// </summary>
        public string ResponseText
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the string of ResponseBody.
        /// </summary>
        /// <returns>The string of ResponseBody.</returns>
        public string GetResponseText()
        {
            return ResponseText;
        }

        /// <summary>
        /// Gets the XElement of ResponseBody(for LINQ to XML).
        /// </summary>
        public XElement XElement
        {
            get
            {
                if (_xElement == null)
                {
                    _xElement = XElement.Parse(ResponseText);
                }

                return _xElement;
            }
        }

        /// <summary>
        /// Gets the XElement of ResponseBody(for LINQ to XML).
        /// </summary>
        /// <returns>The XElement of ResponseBody(for LINQ to XML).</returns>
        public XElement GetXElement()
        {
            return XElement;
        }

        /// <summary>
        /// Gets the method that is used to encode the body of the response.
        /// </summary>
        public string ContentEncoding { get; private set; }

        /// <summary>
        /// Gets the character set of the response.
        /// </summary>
        public string CharacterSet { get; private set; }

        /// <summary>
        /// Gets the length of the content returned by the request.
        /// </summary>
        public long ContentLength { get; private set; }

        /// <summary>
        /// Gets the content type of the response.
        /// </summary>
        public string ContentType { get; private set; }

        /// <summary>
        /// Gets the cookies that are associated with this response.
        /// </summary>
        public CookieCollection Cookies { get; private set; }

        /// <summary>
        /// Gets the headers that are associated with this response from the server.
        /// </summary>
        public WebHeaderCollection Headers { get; private set; }

        /// <summary>
        /// Gets a Boolean value that indicates whether this response was obtained from the cache.
        /// </summary>
        public bool IsFromCache { get; private set; }

        /// <summary>
        /// Gets a Boolean value that indicates whether both client and server were authenticated.
        /// </summary>
        public bool IsMutuallyAuthenticated { get; private set; }

        /// <summary>
        /// Gets the last date and time that the contents of the response were modified.
        /// </summary>
        public DateTime LastModified { get; private set; }

        /// <summary>
        /// Gets the HTTP method that is used to return the response.
        /// </summary>
        public string Method { get; private set; }

        /// <summary>
        /// Gets the version of the HTTP protocol that is used in the response.
        /// </summary>
        public Version ProtocolVersion { get; private set; }

        /// <summary>
        /// Gets the URI of the Internet resource that responded to the request.
        /// </summary>
        public Uri ResponseUri { get; private set; }

        /// <summary>
        /// Gets the name of the server that sent the response.
        /// </summary>
        public string Server { get; private set; }

        /// <summary>
        /// Gets the status of the response.
        /// </summary>
        public HttpStatusCode StatusCode { get; private set; }

        /// <summary>
        /// Gets the status description returned with the response.
        /// </summary>
        public string StatusDescription { get; private set; }
    }
}
